package handler

import (
	"encoding/base64"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
	"markedit/internal/model"
	"markedit/internal/service"
)

type RenderHandler struct {
	renderService *service.RenderService
	logger        *logrus.Logger
}

func NewRenderHandler(renderService *service.RenderService, logger *logrus.Logger) *RenderHandler {
	return &RenderHandler{
		renderService: renderService,
		logger:        logger,
	}
}

// RenderChart 渲染图表
// @Summary 渲染图表
// @Description 渲染Mermaid或PlantUML图表为图片
// @Tags Render
// @Accept json
// @Produce json
// @Param request body model.RenderRequest true "渲染请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/chart [post]
func (h *RenderHandler) RenderChart(c *gin.Context) {
	var request model.RenderRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	var imageData string
	var err error

	switch request.Type {
	case "mermaid":
		imageData, err = h.renderService.RenderMermaidToImage(request.Content, request.Settings)
	case "plantuml":
		imageData, err = h.renderService.RenderPlantUMLToImage(request.Content, request.Settings)
	default:
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Unsupported chart type",
			Message: "Supported types: mermaid, plantuml",
		})
		return
	}

	if err != nil {
		h.logger.Errorf("Failed to render chart: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to render chart",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"image_data": imageData,
			"type":       request.Type,
			"format":     request.Settings["format"],
		},
		Message: "Chart rendered successfully",
	})
}

// PreviewChart 预览图表
// @Summary 预览图表
// @Description 预览生成的图表
// @Tags Render
// @Accept json
// @Produce json
// @Param request body model.RenderRequest true "预览请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/preview [post]
func (h *RenderHandler) PreviewChart(c *gin.Context) {
	var request model.RenderRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind preview request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	// 设置默认格式为SVG（适合预览）
	if request.Settings["format"] == "" {
		request.Settings["format"] = "svg"
	}

	switch request.Type {
	case "plantuml":
		// 直接渲染PlantUML图表
		imageData, err := h.renderService.RenderPlantUMLToImage(request.Content, request.Settings)
		if err != nil {
			h.logger.Errorf("Failed to render PlantUML preview: %v", err)
			c.JSON(http.StatusInternalServerError, model.ErrorResponse{
				Error:   "Failed to generate preview",
				Message: err.Error(),
			})
			return
		}

		c.JSON(http.StatusOK, model.APIResponse{
			Success: true,
			Data: map[string]interface{}{
				"image_data": imageData,
				"type":       request.Type,
				"format":     request.Settings["format"],
			},
			Message: "Preview generated successfully",
		})

	case "mermaid":
		c.JSON(http.StatusOK, model.APIResponse{
			Success: true,
			Data: map[string]interface{}{
				"url":    "", // Mermaid在前端渲染
				"type":   request.Type,
				"format": request.Settings["format"],
			},
			Message: "Mermaid chart ready for client-side rendering",
		})

	default:
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Unsupported chart type",
			Message: "Supported types: mermaid, plantuml",
		})
	}
}

// GetRenderSettings 获取渲染设置
// @Summary 获取渲染设置
// @Description 获取当前渲染服务的配置信息
// @Tags Render
// @Produce json
// @Success 200 {object} model.APIResponse
// @Failure 500 {object} model.ErrorResponse
// @Router /api/render/settings [get]
func (h *RenderHandler) GetRenderSettings(c *gin.Context) {
	// 获取渲染服务设置
	settings := h.renderService.GetRenderSettings()

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    settings,
		Message: "Render settings retrieved successfully",
	})
}

// UpdateRenderSettings 更新渲染设置
// @Summary 更新渲染设置
// @Description 更新渲染服务的配置
// @Tags Render
// @Accept json
// @Produce json
// @Param settings body map[string]interface{} true "渲染设置"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/settings [put]
func (h *RenderHandler) UpdateRenderSettings(c *gin.Context) {
	var settings map[string]interface{}
	if err := c.ShouldBindJSON(&settings); err != nil {
		h.logger.Errorf("Failed to bind render settings: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	// RenderService没有UpdateRenderSettings方法，这里只是返回成功
	// 实际的设置更新应该通过ConfigService处理

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Message: "Render settings updated successfully",
	})
}

// ClearRenderCache 清除渲染缓存
// @Summary 清除渲染缓存
// @Description 清除所有渲染缓存
// @Tags Render
// @Produce json
// @Success 200 {object} model.APIResponse
// @Failure 500 {object} model.ErrorResponse
// @Router /api/render/cache/clear [post]
func (h *RenderHandler) ClearRenderCache(c *gin.Context) {
	h.renderService.ClearCache()

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Message: "Render cache cleared successfully",
	})
}

// GetCacheStats 获取缓存统计
// @Summary 获取缓存统计
// @Description 获取渲染缓存的统计信息
// @Tags Render
// @Produce json
// @Success 200 {object} model.APIResponse
// @Router /api/render/cache/stats [get]
func (h *RenderHandler) GetCacheStats(c *gin.Context) {
	stats := h.renderService.GetCacheStats()

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data:    stats,
		Message: "Cache statistics retrieved successfully",
	})
}

// RenderChartToImage 渲染图表为图片
// @Summary 渲染图表为图片
// @Description 将图表渲染为图片并返回
// @Tags Render
// @Accept json
// @Produce json
// @Param request body model.RenderRequest true "渲染请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/image [post]
func (h *RenderHandler) RenderChartToImage(c *gin.Context) {
	var request model.RenderRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind render request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	var imageDataStr string
	var err error

	switch request.Type {
	case "mermaid":
		imageDataStr, err = h.renderService.RenderMermaidToImage(request.Content, request.Settings)
	case "plantuml":
		imageDataStr, err = h.renderService.RenderPlantUMLToImage(request.Content, request.Settings)
	default:
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Unsupported chart type",
			Message: "Supported types: mermaid, plantuml",
		})
		return
	}

	if err != nil {
		h.logger.Errorf("Failed to render chart to image: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to render chart",
			Message: err.Error(),
		})
		return
	}

	// 将base64字符串解码为字节数组
	imageData, err := base64.StdEncoding.DecodeString(imageDataStr)
	if err != nil {
		h.logger.Errorf("Failed to decode image data: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to decode image data",
			Message: err.Error(),
		})
		return
	}

	// 设置响应头
	format := request.Settings["format"]
	if format == "" {
		format = "png"
	}
	
	c.Header("Content-Type", "image/"+format.(string))
	c.Header("Content-Length", strconv.Itoa(len(imageData)))
	c.Data(http.StatusOK, "image/"+format.(string), imageData)
}

// BatchRender 批量渲染图表
// @Summary 批量渲染图表
// @Description 批量渲染多个图表
// @Tags Render
// @Accept json
// @Produce json
// @Param request body model.BatchRenderRequest true "批量渲染请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/batch [post]
func (h *RenderHandler) BatchRender(c *gin.Context) {
	var request model.BatchRenderRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind batch render request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	results, err := h.renderService.BatchRenderCharts(request.Items)
	if err != nil {
		h.logger.Errorf("Failed to batch render charts: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to batch render charts",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"results": results,
			"total":   len(request.Items),
		},
		Message: "Batch render completed successfully",
	})
}

// RenderMermaid 渲染Mermaid图表
// @Summary 渲染Mermaid图表
// @Description 渲染Mermaid图表为图片
// @Tags Render
// @Accept json
// @Produce json
// @Param request body model.RenderRequest true "渲染请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/mermaid [post]
func (h *RenderHandler) RenderMermaid(c *gin.Context) {
	var request model.RenderRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind mermaid request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	imageData, err := h.renderService.RenderMermaidToImage(request.Content, request.Settings)
	if err != nil {
		h.logger.Errorf("Failed to render mermaid chart: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to render mermaid chart",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"image_data": imageData,
			"type":       "mermaid",
			"format":     request.Settings["format"],
		},
		Message: "Mermaid chart rendered successfully",
	})
}

// RenderPlantUML 渲染PlantUML图表
// @Summary 渲染PlantUML图表
// @Description 渲染PlantUML图表为图片
// @Tags Render
// @Accept json
// @Produce json
// @Param request body model.RenderRequest true "渲染请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/plantuml [post]
func (h *RenderHandler) RenderPlantUML(c *gin.Context) {
	var request model.RenderRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind plantuml request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	imageData, err := h.renderService.RenderPlantUMLToImage(request.Content, request.Settings)
	if err != nil {
		h.logger.Errorf("Failed to render plantuml chart: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to render plantuml chart",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"image_data": imageData,
			"type":       "plantuml",
			"format":     request.Settings["format"],
		},
		Message: "PlantUML chart rendered successfully",
	})
}

// PreviewImage 预览图片
// @Summary 预览图片
// @Description 预览生成的图片
// @Tags Render
// @Accept json
// @Produce json
// @Param request body model.RenderRequest true "预览请求"
// @Success 200 {object} model.APIResponse
// @Failure 400 {object} model.ErrorResponse
// @Router /api/render/preview [post]
func (h *RenderHandler) PreviewImage(c *gin.Context) {
	var request model.RenderRequest
	if err := c.ShouldBindJSON(&request); err != nil {
		h.logger.Errorf("Failed to bind preview request: %v", err)
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Invalid request body",
			Message: err.Error(),
		})
		return
	}

	// 设置默认格式为SVG（适合预览）
	if request.Settings == nil {
		request.Settings = make(map[string]interface{})
	}
	if request.Settings["format"] == nil || request.Settings["format"] == "" {
		request.Settings["format"] = "svg"
	}

	var imageData string
	var err error

	switch request.Type {
	case "mermaid":
		imageData, err = h.renderService.RenderMermaidToImage(request.Content, request.Settings)
	case "plantuml":
		imageData, err = h.renderService.RenderPlantUMLToImage(request.Content, request.Settings)
	default:
		c.JSON(http.StatusBadRequest, model.ErrorResponse{
			Error:   "Unsupported chart type",
			Message: "Supported types: mermaid, plantuml",
		})
		return
	}

	if err != nil {
		h.logger.Errorf("Failed to generate preview: %v", err)
		c.JSON(http.StatusInternalServerError, model.ErrorResponse{
			Error:   "Failed to generate preview",
			Message: err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, model.APIResponse{
		Success: true,
		Data: map[string]interface{}{
			"image_data": imageData,
			"type":       request.Type,
			"format":     request.Settings["format"],
		},
		Message: "Preview generated successfully",
	})
}